package com.hailiang.saas.auth.service;

import com.google.common.collect.Maps;
import com.nimbusds.jose.JOSEException;
import com.nimbusds.jose.jwk.RSAKey;
import org.springframework.security.core.userdetails.UserDetails;

import java.text.ParseException;
import java.util.Map;


/**
 * JWT Token组成: note --> JWT默认是明文展示，任何人都可以读取到，所以此处不要放私密信息
 *
 *  详见文档链接: https://www.cnblogs.com/dwlovelife/p/11321541.html
 *
 *  Header(头部) + Payload(负载) + Signature(签名)  --> 最终生成形式: Header.Payload.Signature
 *
 *      1、Header: JSON对象,需要进行Base64URL算法转成字符串
 *
 *          alg: 签名的算法 默认是: HMAC或SHA256
 *
 *          typ: 令牌类型 JWT令牌统一值为: "JWT"
 *
 *      2、Payload: 负载, JSON对象,需要进行Base64URL算法转成字符串
 *
 *        官方字段:
 *
 *          iss (issuer)：签发人
 *          exp (expiration time)：过期时间
 *          sub (subject)：主题
 *          aud (audience)：受众
 *          nbf (Not Before)：生效时间
 *          iat (Issued At)：签发时间
 *          jti (JWT ID)：编号
 *
 *         自定义字段:
 *
 *          username:
 *          role:
 *          name:
 *          age:
 *          authority:
 *
 *       3、Signature: 签名,对前面两个部分进行，防止数据被篡改，需要随机产生一个secret
 *
 *          过程: 需要指定一个密钥（secret）。这个密钥只有服务器才知道，不能泄露给用户,然后使用 Header 里面指定的签名算法（默认是 HMAC SHA256），按照下面的公式产生签名。
 *
 *       4、最终将Header、Payload、Signature进行拼接，以.号分割
 *
 *          HMACSHA256( base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)
 * */

public interface JwtTokenService {

    public static Map<String, RSAKey> rsaKeyMap = Maps.newConcurrentMap();

    String TOKEN_HEADER = "Authorization";
    String TOKEN_PREFIX = "Bearer ";

    //密钥，用于signature（签名）部分解密
    String PRIMARY_KEY = "jwtsecretdemo";
    // 过期时间是3600秒，既是1个小时
    long EXPIRATION = 3600L;
    // 选择了记住我之后的过期时间为7天
    long EXPIRATION_REMEMBER = 604800L;

    String generateTokenByHMAC(String payloadStr, String secret) throws JOSEException;

    UserDetails verifyTokenByHMAC(String token, String secret) throws ParseException, JOSEException;

    String generateTokenByRSA(String payloadStr, RSAKey rsaKey) throws JOSEException;

    Boolean verifyTokenByRSA(String token) throws ParseException, JOSEException;

    RSAKey generateDefaultRSAKey();

    RSAKey getDefaultRSAKey();
}
